import cv2
from multiprocessing import Process, Event, Queue
import signal
import os
import time


def capture(camera_id, output_queue, stop_event):
    """相机捕获的内部实现"""
    cap = cv2.VideoCapture(camera_id)
    if not cap.isOpened():
        print(f"无法打开相机 {camera_id}")
        return

    def signal_handler(signum, frame):
        stop_event.set()

    signal.signal(signal.SIGTERM, signal_handler)

    try:
        while not stop_event.is_set():
            ret, frame = cap.read()
            if not ret:
                print(f"无法读取相机 {camera_id} 的帧")
                break

            # 将图像数据放入队列，如果队列已满则丢弃旧帧
            if not output_queue.full():
                output_queue.put(frame)
            else:
                try:
                    output_queue.get_nowait()  # 丢弃旧帧
                except:
                    pass
                output_queue.put(frame)

            # 控制采集频率以避免高CPU使用率
            time.sleep(0.01)
    except KeyboardInterrupt:
        print("捕获中断")
    finally:
        cap.release()
        cv2.destroyAllWindows()
        while not output_queue.empty():
            output_queue.get()
        print(f"相机 {camera_id} 停止捕获")


class CameraDriver:
    def __init__(self, camera_id, output_queue):
        """初始化相机驱动

        Args:
            camera_id (int): 相机的ID
            output_queue (Queue): 用于传递图像数据的队列
        """
        self._camera_id = camera_id
        self._output_queue = output_queue
        self._process = None
        self._stop_event = Event()

    def startCapturing(self):
        """启动相机捕获进程"""
        if self._process is None:
            self._process = Process(
                target=capture,
                args=(self._camera_id, self._output_queue, self._stop_event),
            )
            self._process.start()
        else:
            print(f"相机 {self._camera_id} 已启动")

    def stopCapturing(self):
        """停止相机捕获进程"""
        if self._process is not None:
            print(f"停止相机 {self._camera_id} 的捕获...")
            self._stop_event.set()
            os.kill(self._process.pid, signal.SIGTERM)
            self._process.join()
            self._process = None
            self._stop_event.clear()
            print(f"相机 {self._camera_id} 已停止")
